﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace AusProject.OrderComponents
{
    public partial class OrderComponent : UserControl
    {
        private Pen borderPen;

        private int requiredHeight;   // height is not allowed to changed by user

        private ComponentRow lastRow;

        public int Id { get; set; }

        public string Title
        {
            get
            {
                return lblName.Text;
            }
            set
            {
                lblName.Text = value;
            }
        }

        public ComponentRow FirstRow
        {
            get { return row0; }
        }

        public ComponentRow LastRow
        {
            get { return lastRow; }
        }

        private ComponentColumnInfo[] columns;

        public ComponentColumnInfo[] Columns
        {
            get { return columns; }
            set {
                columns = value;
                if (value != null)
                {
                    CreateColumns();
                }
            }
        }

        private void CreateColumns()
        {
            //TODO: change starting index of rows when add new control to this UC
            for (int i = this.Controls.Count - 1; i > 2; i--)
            {
                this.Controls.RemoveAt(i);
            }

            ComponentCell[] cells = new ComponentCell[columns.Length];
            for (int i = 0; i < columns.Length; i++)
            {
                cells[i] = new ComponentCell(columns[i].ShowTitle, columns[i].WidthPercent);
            }
            header.Cells = cells;

            cells = new ComponentCell[columns.Length];
            for (int i = 0; i < columns.Length; i++)
            {
                cells[i] = new ComponentCell(true, columns[i].WidthPercent);

                if (columns[i].ShowTitle)
                {
                    header.SetTextOfCol(i, columns[i].Title);
                }
            }
            row0.Cells = cells;

            this.Invalidate();
        }



        public OrderComponent()
        {
            InitializeComponent();
            borderPen = new Pen(new SolidBrush(Color.Black), 1);

            requiredHeight = header.Height + row0.Height - 1;
            OrderComponent_Resize(null, null);

            lastRow = row0;
        }

        private void OrderComponent_Resize(object sender, EventArgs e)
        {
            this.Height = requiredHeight;
            lblName.Top = header.Top + (header.Height - lblName.Height) / 2;

            //TODO: change starting index of rows when add new control to this UC
            for (int i = 1; i < this.Controls.Count; i++)
            {
                ((ComponentRow)this.Controls[i]).Width = this.Width;
            }
        }


        public ComponentRow AddRow()
        {
            ComponentRow newRow = new ComponentRow();
            newRow.Cells = row0.Cells;
            newRow.Width = row0.Width;
            newRow.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
            newRow.Top = lastRow.Top + row0.Height - 1;
            newRow.IsFirstLine = false;
            newRow.IsLastLine = true;
            newRow.MouseClick += new MouseEventHandler(InvokeRowClicked);
            this.Controls.Add(newRow);

            lastRow.IsLastLine = false;
            lastRow = newRow;

            this.requiredHeight = this.requiredHeight + row0.Height - 1;
            this.Height = requiredHeight;
            Invalidate();

            return newRow;
        }

        public void RemRow(ComponentRow row)
        {
            if (lastRow != row0)  // not allowed to remove the last line
            {
                this.Controls.Remove(row);
                this.Invalidate();

                //TODO: change starting index of rows when add new control to this UC
                row0 = (ComponentRow)this.Controls[2];    // first control is lblName
                row0.IsFirstLine = true;
                row0.Top = header.Height - 1;

                //TODO: change starting index (i) of rows when add new control to this UC
                for (int i = 3; i < this.Controls.Count; i++)
                {
                    ((ComponentRow)this.Controls[i]).Top = row0.Top + (i - 2) * (row0.Height - 1);
                }
                lastRow = (ComponentRow)this.Controls[this.Controls.Count - 1];
                lastRow.IsLastLine = true;

                this.requiredHeight = lastRow.Top + lastRow.Height;
                this.Height = requiredHeight;
                Invalidate();
            }
        }


        #region Event RowMouseClick

        public event EventHandler<RowClickedEventArgs> RowClicked;

        protected void InvokeRowClicked(object sender, MouseEventArgs e)
        {
            if (RowClicked != null)
            {
                Point p = this.PointToClient(((Control)sender).PointToScreen(e.Location));
                RowClicked(this, new RowClickedEventArgs((ComponentRow)sender, new MouseEventArgs(e.Button, e.Clicks, p.X, p.Y, e.Delta)));
            }
        }

        #endregion Event RowMouseClick


        public void SetTextOfCell(int rowIndex, int colIndex, string text)
        {
            //TODO: change starting index of rows when add new control to this UC
            try
            {
                ((ComponentRow)this.Controls[2 + rowIndex]).SetTextOfCol(colIndex, text);
            }
            catch { }
        }

        public string GetTextOfCell(int rowIndex, int colIndex)
        {
            try
            {
                //TODO: change starting index of rows when add new control to this UC
                return ((ComponentRow)this.Controls[2 + rowIndex]).GetTextOfCol(colIndex);
            }
            catch
            {
                return null;
            }
        }

        private void header_MouseClick(object sender, MouseEventArgs e)
        {
            Point p = this.PointToClient(header.PointToScreen(e.Location));
            this.OnMouseClick(new MouseEventArgs(e.Button, e.Clicks, p.X, p.Y, e.Delta));
        }

        private void lblName_MouseClick(object sender, MouseEventArgs e)
        {
            Point p = this.PointToClient(lblName.PointToScreen(e.Location));
            this.OnMouseClick(new MouseEventArgs(e.Button, e.Clicks, p.X, p.Y, e.Delta));
        }


        public void ImportInfo(OrderComponentInfo info)
        {
            Id = info.Id;
            Title = info.Title;
            Width = info.Width;

            ComponentColumnInfo[] columns = new ComponentColumnInfo[info.Columns.Length];
            for (int i = 0; i < columns.Length; i++)
            {
                columns[i] = new ComponentColumnInfo(info.Columns[i].Id, info.Columns[i].Title, info.Columns[i].ShowTitle, info.Columns[i].WidthPercent);
            }

            Columns = columns;
        }

        public OrderComponentInfo ExportInfo()
        {
            ComponentColumnInfo[] columns = new ComponentColumnInfo[this.Columns.Length];
            for (int i = 0; i < columns.Length; i++)
            {
                columns[i] = new ComponentColumnInfo(this.Columns[i].Id, this.Columns[i].Title, this.Columns[i].ShowTitle, this.Columns[i].WidthPercent);
            }

            return new OrderComponentInfo(Title, Width, columns);
        }

        public void Highlight()
        {
            lblName.BackColor = SystemColors.Highlight;
            header.BackColor = SystemColors.Highlight;
        }

        public void Unhighlight()
        {
            lblName.BackColor = Color.Transparent;
            header.BackColor = Color.Transparent;
        }

    }


    public class RowClickedEventArgs : MouseEventArgs
    {
        private ComponentRow row;

        public ComponentRow Row
        {
            get { return row; }
        }

        public RowClickedEventArgs(ComponentRow row, MouseEventArgs e)
            : base(e.Button, e.Clicks, e.X, e.Y, e.Delta)
        {
            this.row = row;
        }
    }
}
